package model.elements;

import control.elements.Caller;
import control.elements.CallerAbilities;
import control.elements.gear.Gear;
import control.elements.helpers.Dark;
import control.elements.helpers.Earth;
import control.elements.helpers.ElementType;
import control.elements.helpers.Fire;
import control.elements.helpers.Ice;
import control.elements.helpers.Light;
import control.elements.helpers.Neutral;
import control.elements.helpers.Thunder;
import control.elements.helpers.Water;
import control.elements.helpers.Wind;

public class Field{
	
	private static ElementType[] element_table;
	static {
		element_table = new ElementType[9];
		element_table[0] = new Light();
		element_table[1] = new Dark();
		element_table[2] = new Fire();
		element_table[3] = new Earth();
		element_table[4] = new Water();
		element_table[5] = new Wind();
		element_table[6] = new Ice();
		element_table[7] = new Thunder();
		element_table[8] = new Neutral();
	}

	private ElementType day_of_week;
	
	private ElementType prim_weather;
	
	private ElementType aux_weather;
	
	private int final_perp;
	
	private int final_skill;
	
	private int final_refresh;
	
	private Caller my_caller;
	
	public Field() {
		day_of_week = new Light();
		prim_weather = new Neutral();
		aux_weather = new Neutral();
	}
	
	/**
	 * 
	 */
	public int getFinalPerp(){
		return final_perp;
	}
	
	/**
	 * Creates a summoner object to use in this program.
	 * 
	 * @param the_name
	 * @param the_lvl
	 * @param the_mp
	 * @return
	 */
	public boolean createSmn(final String the_name,
			final int the_lvl, final int the_mp) {
		boolean result = false;
		if(the_lvl <= 99 && the_lvl > 0) {
			Caller caller = new Caller(the_name, the_lvl, the_mp);
			my_caller = caller;
			result = true;
		} else {
			throw new IllegalArgumentException("Level out of Range");
		}
		return result;
	}
	
	public void clearGearList(){
		my_caller.setDefaultGearList();
	}
	
	public void changeSkill(int the_skill) {
		my_caller.setMySkill(the_skill);
	}
	
	public void changeMP(int the_mp) {
		my_caller.setMyMp(the_mp);
	}
	
	public boolean changeGear(String the_gear) {
		boolean result;
		result = my_caller.setGear(the_gear);
		return result;
	}
	
	public String getPet() {
		return my_caller.getMyPet().toString();
	}
	
	public boolean hasPet() {
		boolean pet = true;
		if(my_caller.getMyPet().getName().equals("None") || my_caller.getMyPet() == null) {
			pet = false;
		}
		return pet;
	}
	
	public double getSiphon(){
		if(my_caller.getMySkill() <= 50) {
			return 0;
		}
		boolean tCape = false;
		boolean tCape2 = false;
		boolean cFeet1 = false;
		boolean cFeet2 = false;
		boolean pants = false;
		for(int i = 0; i < my_caller.getGear().length; i++) {
			if(my_caller.getGear()[i].getName().equals("twilight cape")) {
				tCape = true;
			}
			else if(my_caller.getGear()[i].getName().equals("conveyance cape")) {
				tCape2 = true;
			}
			if(my_caller.getGear()[i].getName().equals("caller's pigaches +1")){
				cFeet1 = true;
			}else if(my_caller.getGear()[i].getName().equals("caller's pigaches +2")){
				cFeet2 = true;
			}
			if(my_caller.getGear()[i].getName().equals("tatsumaki sitagoromo")){
				pants = true;
			}
			
		}
		return CallerAbilities.elementalSiphon(my_caller.getMySkill(),
				pants, cFeet1, cFeet2, tCape,tCape2, 
				my_caller.getMyPet().getElement(), day_of_week,
				prim_weather, aux_weather);
	}
	
	public String getCallerName(){
		return my_caller.getMyName();
	}
	
	public int getCallerMp() {
		return my_caller.getMyMp();
	}
	
	public int getCallerLvl() {
		return my_caller.getMyLvl();
	}
	
	public Gear[] getGearList() {
		return my_caller.getGear();
	}
	/**
	 * 
	 * @param the_ele
	 * @param w2
	 */
	public void setWeather(int the_ele, boolean w2) {
		if(the_ele <= 8 && the_ele >= 0) {
			if(w2) {
				aux_weather = element_table[the_ele];
			}
			prim_weather = element_table[the_ele];
			//System.out.println(prim_weather.toString());
		}	
	}
	
	/**
	 * 
	 * @param the_ele
	 */
	public void setDay(int the_ele) {
		if(the_ele <= 7 && the_ele >= 0) {
			day_of_week = element_table[the_ele];
		}
	}
	
	
	/**
	 * Releases Pet
	 */
	public void Release() {
		my_caller.setMyPet(CallerAbilities.releasePet(my_caller.getMyLvl()));
	}
	
	
	/**
	 * Summons Ifrit.
	 */
	public void Ifrit() {
		my_caller.setMyPet(CallerAbilities.summonIfrit(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Titan.
	 */
	public void Titan() {
		my_caller.setMyPet(CallerAbilities.summonTitan(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Leviathan.
	 */
	public void Leviathan() {
		my_caller.setMyPet(CallerAbilities.summonLevi(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Garuda.
	 */
	public void Garuda() {
		my_caller.setMyPet(CallerAbilities.summonGaru(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Shiva.
	 */
	public void Shiva() {
		my_caller.setMyPet(CallerAbilities.summonShiva(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Ramuh.
	 */
	public void Ramuh() {
		my_caller.setMyPet(CallerAbilities.summonRamuh(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Fenrir.
	 */
	public void Fenrir() {
		my_caller.setMyPet(CallerAbilities.summonFenrir(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Carby.
	 */
	public void Carbuncle() {
		my_caller.setMyPet(CallerAbilities.summonCarby(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Diabolos.
	 */
	public void Diabolos() {
		my_caller.setMyPet(CallerAbilities.summonDiabolos(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Fire Spirit.
	 */
	public void FireSpirit() {
		my_caller.setMyPet(CallerAbilities.summonFireSpirit(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Earth Spirit.
	 */
	public void EarthSpirit() {
		my_caller.setMyPet(CallerAbilities.summonEarthSpirit(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Water Spirit.
	 */
	public void WaterSpirit() {
		my_caller.setMyPet(CallerAbilities.summonWaterSpirit(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Air Spirit.
	 */
	public void AirSpirit() {
		my_caller.setMyPet(CallerAbilities.summonWindSpirit(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Ice Spirit.
	 */
	public void IceSpirit() {
		my_caller.setMyPet(CallerAbilities.summonIceSpirit(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Thunder Spirit.
	 */
	public void ThunderSpirit() {
		my_caller.setMyPet(CallerAbilities.summonThunderSpirit(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Light Spirit.
	 */
	public void LightSpirit() {
		my_caller.setMyPet(CallerAbilities.summonLightSpirit(
				my_caller.getMyLvl()));
	}
	
	/**
	 * Summons Dark Spirit.
	 */
	public void DarkSpirit() {
		my_caller.setMyPet(CallerAbilities.summonDarkSpirit(
				my_caller.getMyLvl()));
	}

	private void calculatePerp() {
		final_perp = my_caller.calculatePerp(day_of_week, prim_weather, aux_weather);
	}
	

	public int getFinalSkill() {
		
		return my_caller.getMySkill();
	}
	
	private void calcMpPerTic() {
		
		final_refresh = final_perp - my_caller.calcRefresh();
		
		if(final_refresh < 0) {
			final_refresh = Math.abs(final_refresh);
			final_perp = 0;
		}
		else { 
			final_perp = final_refresh;
			final_refresh = 0;
			
		}
	}
	
	public int getMpPerTic() {
		calculatePerp();
		calcMpPerTic();
		return final_refresh;
	}

	public boolean hasCaller() {
		if(my_caller == null) {
			return false;
		}
		return true;
	}
}
